
package cn.klandor.picasa.ui;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

public class PhotoPanel extends JPanel {
	
	private static final long serialVersionUID = 1L;
	private BufferedImage img;
	private int w;
	private int h;
	private double scale = 1.0;
	private AffineTransform aTransform = new AffineTransform();
	
	public PhotoPanel(){
		addMouseWheelListener(new ZoomHandler());
		this.img = null;
	}
	public Dimension getPreferredSize() {
        return new Dimension(400, 300);
    }
	
	public void setImg(BufferedImage img) {
		
		this.img = img;
		scale = 1.0;
		w=img.getWidth();
		h=img.getHeight();
		int width = getWidth();
		int height = getHeight();
		if(w>width||h>height){
			if( ((float)width/w) > ((float)height/h)){
				scale = (double)height/h;
			    h= height;    
			    w= (int)(scale*w);
			}else{
			    scale = (double)width/w;
			    w= width;    
			    h= (int)(scale*h);
			}
		}
		aTransform = new AffineTransform();
		aTransform.setToScale(scale, scale);
		repaint();
	}
	
	public boolean isOpaque() {
	     return false;
	}
	
	public void paintComponent(Graphics g) {
		
		if(img == null) return;
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D)g;
		g2.translate((getWidth()-w)/2, (getHeight()-h)/2);
		g2.transform(aTransform);

		g.drawImage(img,0,0,null);
	}
	
	public void zoomUp() {
		if(img == null) return;
		scale += (0.05);
		scale = Math.min(10, scale);

		aTransform.setToScale(scale, scale);

		w=(int)(img.getWidth()*scale);
		h=(int)(img.getHeight()*scale);
		repaint();
	}

	public void zoomIn() {
		if(img == null) return;
		scale -= (0.05);
		scale = Math.max(0.01, scale);
			
		aTransform.setToScale(scale, scale);
			
		w=(int)(img.getWidth()*scale);
		h=(int)(img.getHeight()*scale);
		repaint();
	}

	public void zoomO() {
		w=(int)(w/scale);
		h=(int)(h/scale);
		scale = 1.0;
		aTransform.setToScale(scale, scale);
		repaint();
	}

	public void rotateRight() {
		if(img == null) return;
		AffineTransform at=new AffineTransform();
		at.translate(img.getHeight(), 0);
		at.rotate(Math.toRadians(90));
		AffineTransformOp op=new AffineTransformOp(at,AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
		this.img =op.filter(img, null);
		int tmp = w;
		w= h;
		h= tmp;
		repaint();
	}

	public void rotateLeft() {
		if(img == null) return;
		AffineTransform at=new AffineTransform();
		at.translate(0,img.getWidth());
		at.rotate(Math.toRadians(270));
		AffineTransformOp op=new AffineTransformOp(at,AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
		this.img =op.filter(img, null);
		int tmp = w;
		w= h;
		h= tmp;
		repaint();
	}

	private class ZoomHandler implements MouseWheelListener {

		public void mouseWheelMoved(MouseWheelEvent e) {
			if(img == null) return;
			if(e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
				scale += (0.01 * e.getWheelRotation());
				scale = Math.max(0.01, scale);
				scale = Math.min(10, scale);
				
				aTransform.setToScale(scale, scale);
				
				w=(int)(img.getWidth()*scale);
				h=(int)(img.getHeight()*scale);
				PhotoPanel.this.repaint();
			}
		}
	}

}
